package cn.akwangl.design.pattern.creational.singleton;

import java.io.Externalizable;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;

/**
 * 单例模式v5.恶汉单例
 *
 * <p>
 * 饿汉模式是在类加载的时候直接创建了对象,不存在线程安全问题,它的优点是简单方便,
 * 缺点是如果这个类在不需要创建单例对象的时候就会装载（比如这个类有其它静态方法被调用）的话,
 * 会造成浪费,不过只要遵循单一职责原则,一般不会有这种问题。
 * </p>
 *
 * @author youyongkun
 * @date 2021/11/24 16:48
 */
public class HungrySingleton implements Serializable {

    private static final HungrySingleton instance = new HungrySingleton();

    private HungrySingleton() {
        if (instance != null) {
            throw new RuntimeException("bean singleton creation is not allowed");
        }
    }

    public static HungrySingleton getInstance() {
        return instance;
    }

    /**
     * 防止序列化破坏单例.
     * {@link ObjectInputStream#readOrdinaryObject(boolean)}
     * <p>
     * if (obj != null<br/>
     * && handles.lookupException(passHandle) == null<br/>
     * && desc.hasReadResolveMethod()) {<br/>
     * Object rep = desc.invokeReadResolve(obj);<br/>
     * ....<br/>
     * }<br/>
     * </p>
     * <p>
     * 为什么一定要声明这个方法?其中序列化的过程会去判断,<br/>
     * 目标Object是否实现了{@link Externalizable}或{@link Serializable} 接口,并实现了readResolve方法,序列化时才会被调用.<br/>
     * {@link ObjectStreamClass#ObjectStreamClass(Class<?> cl)}<br/>
     * <code>
     * readResolveMethod = getInheritableMethod(cl, "readResolve", null, Object.class);<br/>
     * </code>
     * </p>
     *
     * @author youyongkun
     * @date 2021/11/24 22:46
     */
    public Object readResolve() {
        return instance;
    }
}
